package org.ala.tiktools.sharddb.mybatis.transaction;

import java.lang.annotation.*;

/**
 * 本地分布式事务注解
 * <p>  在分库分表的场景中，每一个分表会开启一个独立事务，所有分表之间并行预提交，最后统一提交
 * <p>  需要结合 ShardDataSourceTransactionManager 一起使用
 * <p>  如果不开启事务每个分库分表会自行autocommit，没有统一回滚
 *
 * @author ala
 * @date 2025-02-20 09:17
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface ShardTransaction {
    /**
     *  强一致 还是 最终一致
     *  <p> 默认强一致：所有事务会一起提交一起回滚
     *  <p> 若最终一致，则事务操作根据并发方式自行提交，对于失败的自行决定：
     *          是把成功的回滚掉（这里的回滚需要自行补偿，因为此时已经commit成功了）
     *          还是把失败的最终一致掉
     *  <p> 最终一致时，必须提供补偿机制
     *  <p> 但主线程还是会等待所有人的提交结果，只不过占着的链接用完就还（因为要挑出哪些成功的那些失败的，走compensation补偿）
     */
    boolean strongConsistency() default true;
    /**
     *  事务并发方式
     *  <p> 只对强一致有效（只有强一致会一直占着连接）。最终一致时全部并发执行
     *  <p> 分库并发
     *  <p> 每个分库分表一起并发（如果分片很多，瞬时会占用大量连接）
     */
    ConcurrentMannerEnums concurrent() default ConcurrentMannerEnums.Parallel_Shard_Table;
    /**
     *  事务补偿
     *  <p> 只取第0个，这么写搜为了兼容不配的情况
     *  <p> 在预提交阶段的事务如果失败了，全部事务会一起回滚
     *  <p> 但在提交阶段如果失败了，只能走补偿（因为有的真的commit成功了，但有的雀氏失败了）
     *  <p> 这里吧成功的和失败的区分开来，自行决定是把成功的撤销掉还是把失败的最终一致掉
     */
    Class<? extends IShardCompensation>[] compensation() default {};
    /**
     *  事务超时时间
     *  <p> 单位：毫秒
     *  <p> 若这里配置了，以这里为准。否则沿用Shard注解的配置
     */
    long timeout() default 10000l;
}
